package sparql;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import namespaces.NamespaceConstants;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;

public class QueryService {
	private Model rdfGraph;
	private QueryExecutor queryExecutor = new QueryExecutor();

	public QueryService(Model m) {
		rdfGraph = m;
	}

	/**
	 * This SPARQL query matchs only recipes which are in all of three
	 * categories: Time to make, Polutry, and Pasta, rice and grains
	 */
	public List<String> getByCategory() {
		String query = "PREFIX schema: <" + NamespaceConstants.SCHEMA + "> \n"
				+ "SELECT  ?name \n" + "WHERE { \n"
				+ "?recipe a schema:Recipe; \n" + "schema:name ?name; \n"
				+ "schema:recipeCategory \"Pasta\"; \n" + "}";

		List<String> result = queryExecutor
				.executeOneVariableSelectSparqlQuery(query, "name", rdfGraph);

		if (result != null)
			return result;

		return new ArrayList<String>();
	}

	/**
	 * This SPARQL query matchs only recipes which are pastas, and have low
	 * cholesterol, low sugar and high viber content.
	 */
	public List<String> getLowCholesterolLowSugarHighViberPastas() {
		String query = "PREFIX schema: <" + NamespaceConstants.SCHEMA + "> \n"
				+ "PREFIX xsd: <" + NamespaceConstants.XSD + "> \n"
				+ "SELECT DISTINCT ?name \n" + "WHERE { \n"
				+ "?recipe a schema:Recipe; \n" + "schema:name ?name; \n"
				+ "schema:nutrition ?nutrValue. \n"
				+ "?nutrValue a schema:NutritionInformation; \n"
				+ "schema:fiberContent ?fib; \n"
				+ "schema:cholesterolContent ?chol ; \n"
				+ "schema:sugarContent ?sug . \n"
				+ "FILTER(xsd:decimal(?fib) > \"5.0\"^^xsd:decimal && "
				+ "xsd:decimal(?sug) < \"5.0\"^^xsd:decimal && "
				+ "xsd:decimal(?chol) < \"160.0\"^^xsd:decimal)" + "}";

		List<String> result = queryExecutor
				.executeOneVariableSelectSparqlQuery(query, "name", rdfGraph);

		if (result != null)
			return result;

		return new ArrayList<String>();
	}

	/**
	 * This SPARQL query matchs only pasta recipes
	 * which are under 385 calories
	 * and write basic nutrition information about them
	 * OPTIONAL means that value can be unavailable at recipe
	 * but recipe will not be excluded because of that.
	 * 
	 */
	public void getBasicInfoAboutLowCaloriesPastas() {
		String query = "PREFIX schema: <" + NamespaceConstants.SCHEMA + "> \n"
				+ "PREFIX xsd: <" + NamespaceConstants.XSD + "> \n"
				+ "SELECT ?name ?cal ?carbs ?prot ?fat ?sug ?chol ?sat ?sod ?carb \n" + "WHERE { \n"
				+ "?recipe a schema:Recipe; \n" + "schema:name ?name; \n"
				+ "schema:nutrition ?nutrValue; \n"
				+ "schema:recipeCategory \"Pasta\" . \n"
				+ "?nutrValue a schema:NutritionInformation; \n"
				+ "schema:calories ?cal. \n"
				+ "OPTIONAL {?nutrValue schema:fatContent ?fat.} \n"
				+ "OPTIONAL {?nutrValue schema:proteinContent ?prot.} \n"
				+ "OPTIONAL {?nutrValue schema:carbohydrateContent ?carb.} \n"
				+ "OPTIONAL {?nutrValue schema:saturatedFatContent ?sat.} \n"
				+ "OPTIONAL {?nutrValue schema:cholesterolContent ?chol.} \n"
				+ "OPTIONAL {?nutrValue schema:sodmiumContent ?sod.} \n"
				+ "OPTIONAL {?nutrValue schema:fiberContent ?fib.} \n"
				+ "OPTIONAL {?nutrValue schema:sugarContent ?sug.} \n"
				+ "FILTER(xsd:decimal(?cal) < \"385\"^^xsd:decimal)" + "}";

		Query q = QueryFactory.create(query);
		QueryExecution qe = QueryExecutionFactory.create(q, rdfGraph);
		ResultSet resultSet = qe.execSelect();

		while (resultSet.hasNext()) {
			QuerySolution querySolution = resultSet.nextSolution();
			String name = querySolution.getLiteral("name").getLexicalForm();
			System.out.println("Basic nutrition information about recipe "
					+ name);
			if (querySolution.getLiteral("cal") != null) {
				System.out.println("Calories: "
						+ querySolution.getLiteral("cal").getLexicalForm());
			}
			if (querySolution.getLiteral("fat") != null) {
				System.out.println("Fats: "
						+ querySolution.getLiteral("fat").getLexicalForm());
			}
			if (querySolution.getLiteral("prot") != null) {
				System.out.println("Proteins: "
						+ querySolution.getLiteral("prot").getLexicalForm());
			}
			if (querySolution.getLiteral("carb") != null) {
				System.out.println("Carbohydrate Content: "
						+ querySolution.getLiteral("carb").getLexicalForm());
			}
			if (querySolution.getLiteral("sat") != null) {
				System.out.println("Saturated Fat Content: "
						+ querySolution.getLiteral("sat").getLexicalForm());
			}
			if (querySolution.getLiteral("chol") != null) {
				System.out.println("Cholesterol Content: "
						+ querySolution.getLiteral("chol").getLexicalForm());
			}
			if (querySolution.getLiteral("sod") != null) {
				System.out.println("Sodmium Content: "
						+ querySolution.getLiteral("sod").getLexicalForm());
			}
			if (querySolution.getLiteral("fib") != null) {
				System.out.println("Fiber Content: "
						+ querySolution.getLiteral("fib").getLexicalForm());
			}
			if (querySolution.getLiteral("sug") != null) {
				System.out.println("Sugar Content: "
						+ querySolution.getLiteral("sug").getLexicalForm());
			}
		}

		qe.close();

	}
}
